﻿using IntelligentEscalator.DLL;
using IntelligentEscalator.Models;
using System.Data;
using System.Threading;
using System;
using Timer = System.Timers.Timer;
using System.Timers;
using Newtonsoft.Json;
using System.Net.WebSockets;
using System.Text;
using Microsoft.Extensions.Configuration;
using IntelligentEscalator.Tools;
using System.Collections.Generic;
using System.Threading.Tasks;
using IntelligentEscalator.ElevatorWebSocket;
namespace IntelligentEscalator.Helper
{
    public class libdaqHelper
    {

        public bool isConnected = true; // 判断设备连接状态
        public uint ch_len = 8; // 通道数
        public int fs = 32000; // 频率
        public uint datalen = 0; // 数据总长度
        public uint len = 32000; // 通道数据个数
        public Timer _outTimer = null; // 外部定时器
        public Timer _timer = null; // 数据读取定时器
        public bool isStop = false; // 
        public DAQ7100 device_daq7100 = null;//
        public int _timeout = 15;// 默认15秒
        public string device_sn = string.Empty; // 设备序列号
        IConfiguration config = ConfigurationManagerHelper.Configuration;
        public int count = 0; // 记录长时间未获取到数据重新连接
        /// <summary>
        /// 开启一个定时器 定时连接设备
        /// 5秒
        /// </summary>
        public void StartTimer(string sn)
        {
            device_sn = sn;
            InitDeviceAndConnect();
        }

        private void Conn_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            // 定时连接设备 TODO
            if (!isConnected)
            {
                LogHelper.Error("设备断开重新连接");
                InitDeviceAndConnect();
            }
        }


        public void InitDeviceAndConnect()
        {
            try
            {
                Console.WriteLine($"初始化{device_sn}");
                device_daq7100 = new DAQ7100(device_sn);
                // 5.打开采集卡设备
                device_daq7100.device_open();
                // 数据采集
                GetDeviceData();
            }
            catch (Exception ex)
            {
                LogHelper.Error($"设备初始化异常{ex.Message}");
                // 需要重新连接
                isConnected = false;
                CustomDisponse();
            }
        }

        List<double> doubles = new List<double>();// 目标数据量
        public void GetDeviceData()
        {
            try
            {

                // 获取数据
                fs = Convert.ToInt32(config.GetSection("FS").Value);
                len = (uint)Convert.ToInt32(config.GetSection("LEN").Value);
                _timeout = Convert.ToInt32(config.GetSection("TIME").Value);
                datalen = ch_len * len;

                ExcuteTask();
                doubles.Clear();
                count = 0;
                _outTimer = new Timer(_timeout * 1000);
                _outTimer.Elapsed += _outTimer_Elapsed;
                _outTimer.Start();
            }
            catch (Exception ex)
            {
                LogHelper.Error($"GetDeviceData开启读取异常{ex.Message}");
                // 判断连接是否断开
                if (ex.Message.Contains("error code"))
                {
                    // 需要重新连接
                    isConnected = false;
                    CustomDisponse();
                }
            }
        }


        public void ExcuteTask()
        {
            try
            {
                device_daq7100 = new DAQ7100(device_sn);
                int[] adc_ranges = new int[ch_len];
                for (int i = 0; i < ch_len; i++)
                    adc_ranges[i] = 1;
                device_daq7100.ADC.set_propertyIntArrary("InputRange", adc_ranges);
                ////连续采样使用方法
                device_daq7100.ADC.set_propertyString("SampleMode", "Continuous"); //设置连续采样模式                                                               //DAQ-7104,16通道支持以下采样率，200,500,1000,2000,2560,4000,5120,8000,10240,16000,21333
                device_daq7100.ADC.set_propertyInt("Frequency", fs);//采样频率设置为21333
                device_daq7100.ADC.set_propertyInt("Cycles", 0);//设置采样次数，0为连续不间断采样
                device_daq7100.ADC.set_propertyInt("Channels", (int)ch_len);//设置使用的通道数
                //设置触发源
                device_daq7100.ADC.set_propertyString("TriggerSource", "Soft"); //触发源,选择软件触发
                device_daq7100.ADC.sync_channelsetting();// 同步采集卡和libdaq的配置,必须要在设置完所有ADC通道参数后,开始采样之前调用
                device_daq7100.ADC.clear_buffer();// 开始采样前，清除缓冲区数据
                device_daq7100.ADC.send_command("StartTask");  //启动采样任务
                device_daq7100.ADC.send_command("SoftTrigger");//发送软触发信号, 如果触发源设置为硬件触发, 不需要调用

            }
            catch (Exception ex)
            {
                LogHelper.Error($"初始化异常：{ex.Message}");
                if (ex.Message.Contains("error code"))
                {
                    // 需要重新连接
                    isConnected = false;
                    CustomDisponse();
                }
            }
        }

        private void ReadTimer()
        {
            Console.WriteLine($"内部定时开始前的数据{DateTime.Now}数据长度:{doubles.Count}");
            _timer = new Timer(50);
            _timer.Elapsed += _timer_Elapsed;
            _timer.Start();
        }
        private void _timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (isStop) return;
                // 采集个数
                double[] result = new double[datalen];
                uint actual_len = 0;
                device_daq7100.ADC.read_analog(result, datalen, ref actual_len);
                if (actual_len > 0)
                {
                    double[] subArray = new double[actual_len];
                    Array.Copy(result, 0, subArray, 0, actual_len);
                    Console.WriteLine($"内部定时{DateTime.Now.ToString("yyyy-dd-MM HH:mm:ss:fff")}数据个数:{subArray.Length}");
                    doubles.AddRange(subArray);
                }
                if (doubles.Count >= datalen)
                {
                    isStop = true;
                    Console.WriteLine($"数据采集结束!!!!!{doubles.Count}");
                    device_daq7100.ADC.send_command("Stop");// 暂停ADC采样
                    device_daq7100.ADC.send_command("StopTask");//终止采样任务
                                                                // 数据处理
                                                                //if (device_sn == "")

                    List<ChannelData> channels = new List<ChannelData>();
                    for (int ch_index = 0; ch_index < ch_len; ch_index++)
                    {
                        FFTWWrapper fFTWWrapper = new FFTWWrapper();
                        {
                            double[] ch_data = new double[len];
                            device_daq7100.ADC.extract_ChannelAnalogData(doubles.ToArray(), datalen, (byte)ch_len, (byte)ch_index, ch_data);
                            // 计算数据
                            ChannelData channel = fFTWWrapper.CalculateChannelData(ch_index, ch_data, fs, (int)len);
                            channels.Add(channel);
                            LogHelper.LogToTxt((byte)ch_index, ch_data, fs, len, device_sn);
                        }
                        //FFTWWrapper fFTWWrapper = new FFTWWrapper();

                        //LogHelper.LogToTxtFeature((byte)ch_index, channel.FeatureModels, fs, len);
                    }
                    Console.WriteLine($"数据计算结束!!!!!");
                    // 数据websocket推送

                    // 清除数据
                    doubles.Clear();
                    count = 0;
                    // 发送数据
                }
                else count++;
                if (count == 3600)
                {
                    isStop = false;
                    isConnected = false;
                    CustomDisponse();
                }
            }
            catch (Exception ex)
            {
                isStop = false;
                LogHelper.Error(ex.ToString());
                if (ex.Message.Contains("error code"))
                {
                    // 需要重新连接
                    isConnected = false;
                    CustomDisponse();
                }
            }
        }

        private void _outTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                isStop = false;
                doubles.Clear();
                count = 0;
                ExcuteTask();
                if (_timer == null)
                {
                    ReadTimer();
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("外部异常:" + ex.Message);
                if (ex.Message.Contains("error code"))
                {
                    // 需要重新连接
                    isConnected = false;
                    CustomDisponse();
                }
            }
        }
        public void CustomDisponse()
        {
            if (_outTimer != null)
            {
                _outTimer.Stop();
                _outTimer.Dispose();
                _outTimer = null;
            }
            if (_timer != null)
            {
                _timer.Stop();
                _timer.Dispose();
                _timer = null;
            }
        }
    }
}
